/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ruteador.control.geneticAlgorithms;

import java.util.ArrayList;
import java.util.Random;
import ruteador.TSP;

/**
 *
 * @author jorgeorm
 */
public class TSPEvolutivo {
    private ArrayList<IslaTSP> islas;
    private TSP problemaTSP;
    private Random generador;
    private double probMutacion, probSustitucionMalos, probExtinguirMalos,
            probReproducirBuenos, porcExtinsionMax;
    private int generaciones, cotaPoblacion, numeroIslas;
    private boolean islasVivas = false;
    private ArrayList<CromosomaTSP> mejores;
    
    public TSPEvolutivo(TSP problema, int islas, int poblacionMax, int generaciones,
            double mutacion, double sustituirMalos, double extinguirMalos, 
            double reproducirBuenos, double extinsionMax) {
        
        /*Seteo la matriz de distancias
         */
        generador = new Random();
        
        /*Seteo la configuración
         */
        this.numeroIslas = islas;
        this.cotaPoblacion = poblacionMax;
        this.generaciones = generaciones;
        this.probMutacion = mutacion;
        this.probSustitucionMalos = sustituirMalos;
        this.probExtinguirMalos = extinguirMalos;
        this.probReproducirBuenos = reproducirBuenos;
        this.porcExtinsionMax = extinsionMax;
        this.problemaTSP = problema;
        
    }
    
    private void initIslas(){
        islas = new ArrayList(numeroIslas);
        int poblacionIslas = (int) Math.round((double)cotaPoblacion/(double)numeroIslas);
        if(poblacionIslas < 100){
            poblacionIslas = 150;
        }
        
        int maxExtinsion = (int) Math.round((double) poblacionIslas * porcExtinsionMax);
        
        for(int idIsla = 0; idIsla < numeroIslas; idIsla++){
            islas.add(new IslaTSP(generador, problemaTSP.getPuntos().size(),problemaTSP.getPuntoInicial(),
                    poblacionIslas, generaciones,probMutacion, probSustitucionMalos, 
                    probExtinguirMalos,probReproducirBuenos,maxExtinsion, 
                    problemaTSP.getMatrizDistancias()));
        }
    }                
            
    public void resolverProblema(){
        /*TODO: mirar como voy a hacer con el modelo de islas
         */
        for(int idIslas =0; idIslas < numeroIslas; idIslas++){
            /*TODO: Para las islas
             */
//            islas.get(idIslas).run(islas);
            islas.get(idIslas).start();
        }
        
        verificarTerminacion();
    }
    
    private synchronized void verificarTerminacion(){
        
        boolean islitaTermino;
        
        while(!islasVivas){
            try{
                this.wait();
                islasVivas = true;
                for(int idIslas = 0; idIslas < numeroIslas; idIslas++){
                    islitaTermino = islas.get(idIslas).getTermine();
                    if(!islitaTermino){
                        islasVivas= false;
                        break;
                    }
                }
            }catch( InterruptedException excp){
                System.out.println("Error en la verificación de los hilos terminados");
            }
        }
        
        mejores = new ArrayList(numeroIslas);
        
        for(int idIslas = 0; idIslas < numeroIslas; idIslas++){
            mejores.addAll(islas.get(idIslas).getTopCromosomas(1));
        }
        
        System.out.println("Acabo!!!!!!!!!!1");
        
    }
    
}
